﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using System.Net;
using Newtonsoft.Json.Linq;
using System.Web.Mvc;
using EC_ASS.Models;
using PagedList;
using System.Text;
using System.Security.Cryptography;


namespace EC_ASS.Controllers
{
    public class AdminController : Controller
    {
        //
        // GET: /Admin/

        [HttpGet]
        public ActionResult GetAccount()
        {
            if (Session["ADMIN"] != null)
            {
                AdminMShop admin = (AdminMShop)Session["ADMIN"];
                return PartialView("_Account", admin);
            }
            else
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { errors = true });
            }
        }

        [HttpGet]
        public ActionResult Login(string ref_url, string error)
        {
            if (Session["ADMIN"] != null)
            {
                return RedirectToAction("Index", "Admin");
            }
            else
            {
                ViewBag.URL = ref_url;
                if (!String.IsNullOrEmpty(error))
                {
                    ViewBag.MSM = error;
                }
                return View();
            }
        }

        [HttpPost]
        public ActionResult Login(FormCollection form)
        {
            DataECDataContext context = new DataECDataContext();
            try
            {
                AdminMShop admin = context.AdminMShops.Single(tmp => tmp.Account == form.Get("account").ToString()
                                                && tmp.Password == MD5Hash(form.Get("password").ToString()));
                if (admin != null)
                {
                    Session.Add("ADMIN", admin);

                    if (String.IsNullOrEmpty(form.Get("ref_url").ToString()))
                    {
                        return RedirectToAction("Index", "Admin");
                    }
                    else
                    {
                        Session.Add("URL", form.Get("ref_url").ToString());
                        return Redirect(form.Get("ref_url").ToString());
                    }
                }
            }
            catch (System.Exception ex)
            {
                ViewBag.ERROR = "Sai thông tin.";
            }
            return RedirectToAction("Login", "Admin", new { error = ViewBag.ERROR });
        }

        // Logout
        public ActionResult LogOut()
        {
            if (Session["ADMIN"] != null)
            {
                Session.Remove("ADMIN");
            }
            return RedirectToAction("Index", "Admin");
        }

        /* Manage items */

        // List items
        public ActionResult Index(int page = 1)
        {
            if (Session["ADMIN"] == null)
            {
                return RedirectToAction("Login", "Admin");
            }
            else
            {
                DataECDataContext context = new DataECDataContext();
                var itemList = context.Products.ToList();
                return View(itemList.ToPagedList(page, 10));
            }
        }

        // PartialView for reload
        [HttpGet]
        public ActionResult _ListItem(int page = 1)
        {
            DataECDataContext context = new DataECDataContext();
            var itemList = context.Products.ToList();
            return View(itemList.ToPagedList(page, 10));
        }

        // Add items
        [HttpGet]
        public ActionResult AddItem()
        {
            DataECDataContext context = new DataECDataContext();
            var categories = context.Categories.ToList();
            //return PartialView("_AddItem", categories);
            return PartialView("_AddItemPage", categories);
        }

        [HttpPost]
        public ActionResult AddItem(Product item, HttpPostedFileBase f1, HttpPostedFileBase[] f2
                                    , HttpPostedFileBase f3)
        {
            ViewBag.AB = item.Name;
            DataECDataContext context = new DataECDataContext();
            item.View = 0;
            item.NumOfSold = 0;
            item.ID = GenerateID(5);
            item.InsertDate = DateTime.Now;

            // Upload images and html file

            // Set save path to database
            string saveToDBPicturePath = "";
            string saveToDBPictureDetailPath = "";
            string saveToDBDescriptionPath = "";

            string tmp1 = f1.FileName;
            string tmp1Name = Path.GetFileName(tmp1).Replace(' ', '-');
            string tmp1SavePath = Path.Combine(Server.MapPath("~/img/product"), tmp1Name);
            item.Picture = saveToDBPicturePath + "img/product/" + tmp1Name;
            f1.SaveAs(tmp1SavePath);

            foreach (HttpPostedFileBase file in f2)
            {
                string tmp2 = file.FileName;
                string tmp2Name = Path.GetFileName(tmp2).Replace(' ', '-');
                string tmp2SavePath = Path.Combine(Server.MapPath("~/img/detail"), tmp2Name);
                file.SaveAs(tmp2SavePath);
                string url = "_img/detail/" + tmp2Name;
                saveToDBPictureDetailPath += url;
            }
            item.Detail_Images = saveToDBPictureDetailPath;

            string tmp3 = f3.FileName;
            string tmp3Name = Path.GetFileName(tmp3).Replace(' ', '-');
            string tmp3SavePath = Path.Combine(Server.MapPath("~/img/detail"), tmp3Name);
            item.Description = saveToDBDescriptionPath + "img/detail/" + tmp3Name;
            f3.SaveAs(tmp3SavePath);

            // Save product
            context.Products.InsertOnSubmit(item);
            context.SubmitChanges();
            ViewBag.MS = "Thêm sản phẩm thành công";
            return RedirectToAction("Index", "Admin");
        }

        // Edit items
        [HttpGet]
        public ActionResult EditItem(string id)
        {
            DataECDataContext context = new DataECDataContext();
            ViewBag.SelectedItem = context.Products.Single(tmp => tmp.ID.Equals(id));
            var categories = context.Categories.ToList();
            return PartialView("_EditPage", categories);
        }

        [HttpPost]
        public ActionResult EditItem(FormCollection form)
        {
            DataECDataContext context = new DataECDataContext();
            Product selectedItem = context.Products.Single(tmp => tmp.ID.Equals(form.Get("ID").ToString()));
            selectedItem.Name = (string)form.Get("Name");
            selectedItem.NumOfProduct = Int32.Parse(form.Get("NumOfProduct"));
            selectedItem.Size = (string)form.Get("Size");
            selectedItem.Source = (string)form.Get("Source");
            selectedItem.Price = Double.Parse(form.Get("Price"));
            context.SubmitChanges();
            ViewBag.EMS = "Cập nhật thành công";
            var categories = context.Categories.ToList();
            return PartialView("_EditPage", categories);
        }

        // Delete items
        [HttpGet]
        public ActionResult DelateItem(string id)
        {
            DataECDataContext context = new DataECDataContext();
            // Find all reference from Deals
            var deals = context.Product_Deals.Where(tmp => tmp.ID.Equals(id));
            if (deals.Count() > 0)
            {
                foreach (Product_Deal item in deals)
                {
                    context.Product_Deals.DeleteOnSubmit(item);
                    context.SubmitChanges();
                }
            }

            // Delete product
            var selectedItem = context.Products.Single(tmp => tmp.ID.Equals(id));
            context.Products.DeleteOnSubmit(selectedItem);
            context.SubmitChanges();
            return RedirectToAction("Index", "Admin");
        }

        /* Manage category */

        // List categories
        public ActionResult Category()
        {
            if (Session["ADMIN"] == null)
            {
                return RedirectToAction("Login", "Admin");
            }
            else
            {
                DataECDataContext context = new DataECDataContext();
                var categories = context.Categories.OrderByDescending(tmp => tmp.ID).ToList();
                return View(categories);
            }
        }

        [HttpGet]
        public ActionResult _ListCategory()
        {
            DataECDataContext context = new DataECDataContext();
            var categories = context.Categories.OrderByDescending(tmp => tmp.ID).ToList();
            return View(categories);
        }

        // Edit categories
        [HttpGet]
        public ActionResult EditCategory(string id)
        {
            DataECDataContext context = new DataECDataContext();
            var selectedItem = context.Categories.Single(tmp => tmp.ID == Int32.Parse(id));
            return PartialView("_EditCategoryPage", selectedItem);
        }

        [HttpPost]
        public ActionResult EditCategory(string id, FormCollection form)
        {
            DataECDataContext context = new DataECDataContext();
            var selectedItem = context.Categories.Single(tmp => tmp.ID == Int32.Parse(id));
            if (selectedItem != null)
            {
                // Update info
                selectedItem.Name = form.Get("Name").ToString();
                selectedItem.Description = form.Get("Description").ToString();
                selectedItem.Prefix = form.Get("Prefix").ToString();
                context.SubmitChanges();
                return Json(new { success = true });
            }
            else
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { errors = true });
            }
        }

        // Add categories
        [HttpGet]
        public ActionResult AddCategory()
        {
            return PartialView("_AddCategoryPage");
        }

        [HttpPost]
        public ActionResult AddCategory(Category item)
        {
            DataECDataContext context = new DataECDataContext();
            context.Categories.InsertOnSubmit(item);
            context.SubmitChanges();
            ViewBag.CMSG = "Thêm thành công!";
            return PartialView("_AddCategoryPage");
        }

        // Delete categories
        [HttpGet]
        public ActionResult DeleteCategory(string id)
        {
            DataECDataContext context = new DataECDataContext();
            var selectedItem = context.Categories.Single(tmp => tmp.ID == Int32.Parse(id));
            if (selectedItem != null)
            {
                context.Categories.DeleteOnSubmit(selectedItem);
                context.SubmitChanges();
                return Json(new { success = true });
            }
            else
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { errors = true });
            }
        }

        /* Manage feedback */

        // List feedback
        public ActionResult Feedback()
        {

            if (Session["ADMIN"] == null)
            {
                return RedirectToAction("Login", "Admin");
            }
            else
            {
                DataECDataContext context = new DataECDataContext();
                var feedbackList = context.Feedbacks.OrderByDescending(tmp => tmp.Time).ToList();
                return View(feedbackList);
            }
        }

        // List feedback for reload only
        [HttpGet]
        public ActionResult _ListFeedbackPage()
        {
            DataECDataContext context = new DataECDataContext();
            var feedbackList = context.Feedbacks.OrderByDescending(tmp => tmp.Time).ToList();
            return View(feedbackList);
        }

        // Delete feedback
        [HttpGet]
        public ActionResult DeleteFeedback(string id)
        {
            DataECDataContext context = new DataECDataContext();
            var selectedItem = context.Feedbacks.Single(tmp => tmp.ID == Int32.Parse(id));
            if (selectedItem != null)
            {
                context.Feedbacks.DeleteOnSubmit(selectedItem);
                context.SubmitChanges();
                return Json(new { success = true });
            }
            else
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return Json(new { errors = true });
            }
        }

        //Edit feedback
        [HttpGet]
        public ActionResult EditFeedback(string id)
        {
            DataECDataContext context = new DataECDataContext();
            var selectedItem = context.Feedbacks.Single(tmp => tmp.ID == Int32.Parse(id));
            return PartialView("_EditFeedbackPage", selectedItem);
        }

        [HttpPost]
        public ActionResult EditFeedback(string id, Feedback item)
        {
            DataECDataContext context = new DataECDataContext();
            var selectedItem = context.Feedbacks.Single(tmp => tmp.ID == Int32.Parse(id));
            selectedItem.Customer = item.Customer;
            selectedItem.Email = item.Email;
            selectedItem.Content = item.Content;
            context.SubmitChanges();
            return Json(new { success = true });
        }


        /************************************************************************/
        /* Manage orders                                                        */
        /************************************************************************/

        // List orders
        public ActionResult Order()
        {
            if (Session["ADMIN"] == null)
            {
                return RedirectToAction("Login", "Admin");
            }
            else
            {
                DataECDataContext context = new DataECDataContext();
                var orderList = context.Orders.ToList();
                return View(orderList);
            }

        }

        // Reload orders
        public ActionResult _LoadOrder()
        {
            DataECDataContext context = new DataECDataContext();
            var orderList = context.Orders.ToList();
            return PartialView("_ListOrder", orderList);
        }

        // Delere orders
        [HttpGet]
        public ActionResult DeleteOrder(string id)
        {
            DataECDataContext context = new DataECDataContext();
            var selectedItem = context.Orders.Single(tmp => tmp.ID == Int32.Parse(id));
            context.Orders.DeleteOnSubmit(selectedItem);
            context.SubmitChanges();
            return Json(new { success = true });
        }

        // Update orders
        [HttpGet]
        public ActionResult UpdateOrder(string id)
        {
            DataECDataContext context = new DataECDataContext();
            var selectedItem = context.Orders.Single(tmp => tmp.ID == Int32.Parse(id));
            return PartialView("_EditOrderPage", selectedItem);
        }

        [HttpPost]
        public ActionResult UpdateOrder(Order item)
        {
            DataECDataContext context = new DataECDataContext();
            var selectedItem = context.Orders.Single(tmp => tmp.ID == item.ID);
            selectedItem.Note = item.Note;
            selectedItem.Buyer = item.Buyer;
            selectedItem.BuyerPhone = item.BuyerPhone;
            selectedItem.Receiver = item.Receiver;
            selectedItem.ShipAddress = item.ShipAddress;
            selectedItem.ShipPhone = item.ShipPhone;
            selectedItem.ShipFee = item.ShipFee;
            selectedItem.Total = item.Total;
            selectedItem.CheckedOut = item.CheckedOut;
            context.SubmitChanges();
            return Json(new { success = true });
        }

        // Get order detail
        [HttpGet]
        public ActionResult OrderDetail(string id)
        {
            DataECDataContext context = new DataECDataContext();
            var detailList = (from p in context.Products
                              join ord in context.DetailOrders on p.ID equals ord.ProductID
                              where ord.OrderID == Int32.Parse(id)
                              select new OrderDetailModel { DetailItem = p, Orders = ord }).ToList();
            return PartialView("_LoadDetailOrder", detailList);
        }

        // Update detail orders
        [HttpPost]
        public ActionResult UpdateDetailOrderItem(string id, string quantity)
        {
            DataECDataContext context = new DataECDataContext();
            DetailOrder detail = context.DetailOrders.Single(tmp => tmp.ID == Int32.Parse(id));
            if (detail != null)
            {
                double price = detail.Price.GetValueOrDefault();

                // Update new total price of order
                Order order = context.Orders.Single(tmp => tmp.ID == detail.OrderID);
                if (detail.Quantity > Int32.Parse(quantity))
                {
                    order.Total -= price * (detail.Quantity - Int32.Parse(quantity));
                }
                else if (detail.Quantity < Int32.Parse(quantity))
                {
                    order.Total += price * (Int32.Parse(quantity) - detail.Quantity);
                }
                // Update quantity
                detail.Quantity = Int32.Parse(quantity);
                context.SubmitChanges();
            }
            return RedirectToAction("OrderDetail", new { id = id });
        }

        // Delete detail items
        [HttpGet]
        public ActionResult DeleteDetailItem(string id, string size, string order)
        {
            DataECDataContext context = new DataECDataContext();
            try
            {
                var selectedItem = context.DetailOrders.Single(tmp => tmp.ID == Int32.Parse(id)
                                                      && tmp.OrderID == Int32.Parse(order)
                                                      && tmp.Size == size);
                var selectedOrder = context.Orders.Single(tmp => tmp.ID == Int32.Parse(order));
                // Update total
                selectedOrder.Total -= selectedItem.Quantity * selectedItem.Price.GetValueOrDefault();

                context.DetailOrders.DeleteOnSubmit(selectedItem);
                context.SubmitChanges();
                return RedirectToAction("OrderDetail", new { id = order });
            }
            catch (System.Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
            }
            return Json(new { errors = true, erroCode = (int)HttpStatusCode.BadRequest });
        }

        // Manage customer membership
        [HttpGet]
        public ActionResult Customer()
        {
            DataECDataContext context = new DataECDataContext();
            var customerList = context.Customers.ToList();
            return View(customerList);
        }

        [HttpGet]
        public ActionResult LoadCustomer()
        {
            DataECDataContext context = new DataECDataContext();
            var customerList = context.Customers.ToList();
            return PartialView("_ListCustomer", customerList);
        }

        // UpgradeVIP
        [HttpGet]
        public ActionResult UpgradeVIP(string id)
        {
            DataECDataContext context = new DataECDataContext();
            try
            {
                var foundedCustomer = context.Customers.Single(tmp => tmp.ID == Int32.Parse(id));
                foundedCustomer.VIP = true;
                foundedCustomer.VIPCard = "img/vip.gif";
                context.SubmitChanges();
                return Json(new { success = true });
            }
            catch (System.Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
            }
            return Json(new { errors = true, errorCode = (int)HttpStatusCode.BadRequest });
        }

        // UpgradeVIP
        [HttpGet]
        public ActionResult DegradeVIP(string id)
        {
            DataECDataContext context = new DataECDataContext();
            try
            {
                var foundedCustomer = context.Customers.Single(tmp => tmp.ID == Int32.Parse(id));
                foundedCustomer.VIP = false;
                foundedCustomer.VIPCard = "";
                context.SubmitChanges();
                return Json(new { success = true });
            }
            catch (System.Exception ex)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
            }
            return Json(new { errors = true, errorCode = (int)HttpStatusCode.BadRequest });
        }

        // Get amount
        [HttpGet]
        public ActionResult GetAmount(string id)
        {
            DataECDataContext context = new DataECDataContext();
            var customerOrders = context.Orders.Where(tmp => tmp.CustomerID == Int32.Parse(id) && tmp.CheckedOut == true).ToList();
            ViewBag.Total = 0;
            foreach (Order item in customerOrders){
                ViewBag.Total += item.Total;
            }
            return PartialView("_CustomerAmount");
        }

        private string MD5Hash(string text)
        {
            MD5 md5 = new MD5CryptoServiceProvider();

            //compute hash from the bytes of text
            md5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(text));

            //get hash result after compute it
            byte[] result = md5.Hash;

            StringBuilder strBuilder = new StringBuilder();
            for (int i = 0; i < result.Length; i++)
            {
                //change it into 2 hexadecimal digits
                //for each byte
                strBuilder.Append(result[i].ToString("x2"));
            }
            return strBuilder.ToString();
        }

        // Random ID  
        private string GenerateID(int lengh)
        {
            var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            var random = new Random();
            var result = new string(
                Enumerable.Repeat(chars, lengh)
                          .Select(s => s[random.Next(s.Length)])
                          .ToArray());
            return result;
        }
    }
}
